package com.rjgf.common.utils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * gitee仓库地址 https://gitee.com/xiaoweidumpb/mz-time
 *
 * @author weimingzhong
 * @date 2022-09-15
 */
public class MzDateUtil {

    /**
     * 标准时间格式
     */
    public static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /**
     * 年,字典key
     */
    public static final String MY_YEAR = "YY";
    /**
     * 月,字典key
     */
    public static final String MY_MONTH = "MM";
    /**
     * 天,字典key
     */
    public static final String MY_DAY = "dd";
    /**
     * 小时,字典key
     */
    public static final String MY_HOUR = "HH";


    /**
     * 获取当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    /**
     * 当前日期的清除小时、分钟、秒
     */
    public static Date nowDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 在原日期的基础上增加分钟
     *
     * @param date   日期
     * @param minute 分钟
     */
    public static Date afterMinute(Date date, int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minute);
        return c.getTime();
    }

    /**
     * 在原日期的基础上增加小时
     *
     * @param date 日期
     * @param hour 小时
     */
    public static Date afterHour(Date date, int hour) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR_OF_DAY, hour);
        return c.getTime();
    }

    /**
     * 在原日期的基础上增加天数
     *
     * @param date 日期
     * @param day  天数
     */
    public static Date afterDay(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, day);
        return c.getTime();
    }

    /**
     * 在原日期的基础上减去分钟
     *
     * @param date   日期
     * @param minute 分钟
     */
    public static Date beforeMinute(Date date, int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, -minute);
        return c.getTime();
    }

    /**
     * 在原日期的基础上减去小时
     *
     * @param nowDate 当前时间
     * @param hour    小时
     */
    public static Date beforeHour(Date nowDate, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);
        // HOUR_OF_DAY 指示一天中的小时 */
        calendar.add(Calendar.HOUR_OF_DAY, -hour);
        // 将分钟、秒、毫秒设置为0 influxDb 时间戳必须精细
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 在原日期的基础上减去天数
     *
     * @param nowDate 当前时间
     * @param day     天数
     */
    public static Date beforeDay(Date nowDate, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);
        // DAY_OF_MONTH 设置为前一天
        calendar.add(Calendar.DAY_OF_MONTH, -day);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取当前时间减去month的时间
     *
     * @param nowDate 当前时间
     * @param month   月份
     * @return 前month月份时间
     */
    public static Date beforeMonth(Date nowDate, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);
        calendar.add(Calendar.MONTH, -month);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 字符串转换成日期
     *
     * @param str 时间字符串
     */
    public static Date strToDate(String str) {
        SimpleDateFormat format = new SimpleDateFormat(TIME_FORMAT);
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 日期转换成字符串
     *
     * @param date 时间
     */
    public static String dayToString(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
        return sdf.format(date);
    }

    /**
     * 日期转换成时间戳
     *
     * @param date 日期
     */
    public static String dateToTimestamp(Date date) {
        return String.valueOf(date.getTime());
    }


    /**
     * 获得时间的年-月-日-时
     *
     * @param date 时间
     */
    public static Map<String, Integer> getDateYYMMDDHH(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Map<String, Integer> map = new HashMap<String, Integer>(16);
        map.put(MY_YEAR, calendar.get(Calendar.YEAR));
        map.put(MY_MONTH, calendar.get(Calendar.MONTH) + 1);
        map.put(MY_DAY, calendar.get(Calendar.DATE));
        map.put(MY_HOUR, calendar.get(Calendar.HOUR_OF_DAY));
        return map;
    }

    /**
     * 计算两个时间差
     *
     * @param nowDate 当前时间
     * @param endDate 结束时间
     */
    public static String getDatePoor(Date nowDate, Date endDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    /**
     * 判断时间是否在时间段内
     *
     * @param nowTime   当前时间
     * @param beginTime 开始时间
     * @param endTime   结束时间
     */
    public static boolean dateBetween(Date nowTime, Date beginTime, Date endTime) {
        //边界值返回
        if (nowTime.getTime() == beginTime.getTime() || nowTime.getTime() == endTime.getTime()) {
            return true;
        }
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        return date.after(begin) && date.before(end);
    }

    /**
     * 判断时间是否在时间段内,忽略年月日
     *
     * @param nowTime   当前时间
     * @param beginTime 开始时间
     * @param endTime   结束时间
     */
    public static boolean dateBetweenIgnoreYYMMDD(Date nowTime, Date beginTime, Date endTime) {


        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        //把年月日设置相等再比较
        //年
        date.set(Calendar.YEAR, begin.get(Calendar.YEAR));
        //月
        date.set(Calendar.MONTH, begin.get(Calendar.MONTH));
        //日
        date.set(Calendar.DAY_OF_MONTH, begin.get(Calendar.DAY_OF_MONTH));

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        //边界值返回
        if (nowTime.getTime() == beginTime.getTime() || nowTime.getTime() == endTime.getTime()) {
            return true;
        }
        return date.after(begin) && date.before(end);
    }


    /**
     * 判断时间是否在时间段内,忽略时分秒
     *
     * @param nowTime   当前时间
     * @param beginTime 开始时间
     * @param endTime   结束时间
     */
    public static boolean dateBetweenIgnoreHHMMSS(Date nowTime, Date beginTime, Date endTime) {
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        //把时分秒设置相等再比较
        //时
        date.set(Calendar.HOUR_OF_DAY, begin.get(Calendar.HOUR_OF_DAY));
        //分
        date.set(Calendar.MINUTE, begin.get(Calendar.MINUTE));
        //秒
        date.set(Calendar.SECOND, begin.get(Calendar.SECOND));
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        //边界值返回
        if (nowTime.getTime() == beginTime.getTime() || nowTime.getTime() == endTime.getTime()) {
            return true;
        }
        return date.after(begin) && date.before(end);
    }

    /**
     * 判断是周末
     *
     * @param nowDate 当前时间
     */
    public static Boolean isWeekend(Date nowDate) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(nowDate);
        return cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
    }


    /**
     * 判断是同一天，用于跳过国家法定节假日
     *
     * @param Date1 日期1
     * @param Date2 日期2
     */
    public static Boolean isSameDay(Date Date1, Date Date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(Date1);
        cal2.setTime(Date2);
        return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
    }

    /**
     * 获取星期一:1,星期二:2,星期三:3,... ...枚举。
     *
     * @param calendar 日历类
     */
    public static Integer getWeekDayNumber(Calendar calendar) {
        //一周第一天是否为星期天
        boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY);
        //国外星期天是1 中国星期一是1
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
        if (isFirstSunday) {
            weekDay = weekDay - 1;
            if (weekDay == 0) {
                weekDay = 7;
            }
        }
        return weekDay;
    }

    /**
     * 10位时间戳转Date
     *
     * @param timestamp 时间戳
     */
    public static Date timestampToDate(Integer timestamp) {
        long temp = (long) timestamp * 1000;
        Timestamp ts = new Timestamp(temp);
        Date date = new Date();
        try {
            date = ts;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }


    /**
     * Date类型转换为10位时间戳
     *
     * @param date 时间
     */
    public static Integer DateToTimestamp(Date date) {
        Timestamp ts = new Timestamp(date.getTime());
        return (int) ((ts.getTime()) / 1000);
    }

}
